//
//  YCPopupController.m
//  YCAlertController
//
//  Created by Yochia on 2017/3/9.
//  Copyright © 2017年 Team Brutal. All rights reserved.
//

#import "YCPopupController.h"
#import "YCPopupPresentAnimation.h"
#import "YCPopupDismissAnimation.h"

@interface YCPopupController () <UIViewControllerTransitioningDelegate> {
    CGFloat _viewHeight;
}

@property (nonatomic, strong) UIView * backgroundView;

@property (nonatomic, strong) NSMutableArray <NSLayoutConstraint *> * constraints;

@property (nonatomic, weak) YCPopupView * oldPopupView;

@end

@implementation YCPopupController

#pragma mark - Init

- (instancetype)init {
    if (self = [super init]) {
        self.modalPresentationStyle = UIModalPresentationCustom;
        self.transitioningDelegate = self;
        [self createAllView];
    }
    return self;
}

#pragma mark - LifeCircle

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    _viewHeight = self.view.frame.size.height;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShown:)
                                                 name:UIKeyboardWillShowNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHidden:)
                                                 name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)keyboardWillShown:(NSNotification *)aNotification {
    NSDictionary * info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    CGFloat kbHeight = kbSize.height;
    
    NSValue *animationDurationValue = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval animationDuration;
    [animationDurationValue getValue:&animationDuration];
    
    [UIView animateWithDuration:animationDuration animations:^{
        self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y,
                                     self.view.frame.size.width, _viewHeight - kbHeight);
        [self.view layoutIfNeeded];
    }];
}

- (void)keyboardWillHidden:(NSNotification *)aNotification {
    NSDictionary * info = [aNotification userInfo];

    NSValue *animationDurationValue = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval animationDuration;
    [animationDurationValue getValue:&animationDuration];
    
    [UIView animateWithDuration:animationDuration animations:^{
        self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y,
                                     self.view.frame.size.width, _viewHeight);
        [self.view layoutIfNeeded];
    }];
}

#pragma mark - 构建视图

- (void)createAllView {
    self.view.backgroundColor = [UIColor clearColor];
    
    self.backgroundView = [UIView new];
    self.backgroundView.translatesAutoresizingMaskIntoConstraints = NO;
    self.backgroundView.backgroundColor = [UIColor blackColor];
    self.backgroundView.alpha = 0.4;
    [self.view addSubview:self.backgroundView];
}

- (void)setPopupViewWithAlertHandler:(void (^)(YCAlertView *))configurationHandler {
    _preferredStyle = YCPopupControllerStyleAlert;
    if (![_popupView isKindOfClass:[YCAlertView class]]) {
        [self hideOldPopupView];
        _popupView = [[YCAlertView alloc] init];
        [self showNewPopupView];
    }
    configurationHandler((YCAlertView *)_popupView);
}

- (void)setPopupViewWithHUDHandler:(void (^)(YCHUDView * hudView))configurationHandler {
    _preferredStyle = YCPopupControllerStyleHUD;
    if (![_popupView isKindOfClass:[YCHUDView class]]) {
        [self hideOldPopupView];
        _popupView = [[YCHUDView alloc] init];
        [self showNewPopupView];
    }
    configurationHandler((YCHUDView *)_popupView);
}

- (void)hideOldPopupView {
    if (_popupView) {
        self.oldPopupView = _popupView;
        [self.oldPopupView popupViewDisappearAnimationOrigin];
        [UIView animateWithDuration:0.3 animations:^{
            [self.oldPopupView popupViewDisappearAnimationDestination];
        } completion:^(BOOL finished) {
            [self.oldPopupView removeFromSuperview];
        }];
    }
}

- (void)showNewPopupView {
    _popupView.controller = self;
    _popupView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:_popupView];
    [_popupView popupViewAppearAnimationOrigin];
    [UIView animateWithDuration:0.3 animations:^{
        [_popupView popupViewAppearAnimationDestination];
    }];
}

#pragma mark - 更新约束

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    [self.view removeConstraints:self.constraints];
    self.constraints = [NSMutableArray array];
    
    if (self.backgroundView) {
        [self layoutBackgroundView];
    }
    
    if (self.popupView) {
        [self layoutAlertConstraint];
    }
    
    if (self.oldPopupView) {
        [self layoutOldConstraint];
    }
    
    [self.view addConstraints:self.constraints];
}

- (void)layoutBackgroundView {
    NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[background]|" options:0 metrics:nil
                                                                 views:@{@"background": self.backgroundView}];
    [self.constraints addObjectsFromArray:consts];
    consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[background]|" options:0 metrics:nil
                                                       views:@{@"background": self.backgroundView}];
    [self.constraints addObjectsFromArray:consts];
}

- (void)layoutAlertConstraint {
    NSLayoutConstraint * centerX = [NSLayoutConstraint constraintWithItem:self.popupView attribute:NSLayoutAttributeCenterX
                                 relatedBy:NSLayoutRelationEqual toItem:self.view
                                 attribute:NSLayoutAttributeCenterX multiplier:1.0
                                  constant:0.0];
    [self.constraints addObject:centerX];
    
    NSLayoutConstraint * centerY = [NSLayoutConstraint constraintWithItem:self.popupView attribute:NSLayoutAttributeCenterY
                                 relatedBy:NSLayoutRelationEqual toItem:self.view
                                 attribute:NSLayoutAttributeCenterY multiplier:1.0
                                  constant:0.0];
    [self.constraints addObject:centerY];

    NSLayoutConstraint * width = [NSLayoutConstraint constraintWithItem:self.popupView attribute:NSLayoutAttributeWidth
                                 relatedBy:NSLayoutRelationEqual toItem:nil
                                 attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0
                                  constant:280];
    [self.constraints addObject:width];

    NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=20)-[alert]-(>=20)-|" options:0 metrics:nil views:@{@"alert": self.popupView}];
    [self.constraints addObjectsFromArray:consts];
}

- (void)layoutOldConstraint {
    NSLayoutConstraint * centerX = [NSLayoutConstraint constraintWithItem:self.oldPopupView attribute:NSLayoutAttributeCenterX
                                                                relatedBy:NSLayoutRelationEqual toItem:self.view
                                                                attribute:NSLayoutAttributeCenterX multiplier:1.0
                                                                 constant:0.0];
    [self.constraints addObject:centerX];
    
    NSLayoutConstraint * centerY = [NSLayoutConstraint constraintWithItem:self.oldPopupView attribute:NSLayoutAttributeCenterY
                                                                relatedBy:NSLayoutRelationEqual toItem:self.view
                                                                attribute:NSLayoutAttributeCenterY multiplier:1.0
                                                                 constant:0.0];
    [self.constraints addObject:centerY];
    
    NSLayoutConstraint * width = [NSLayoutConstraint constraintWithItem:self.oldPopupView attribute:NSLayoutAttributeWidth
                                                              relatedBy:NSLayoutRelationEqual toItem:nil
                                                              attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0
                                                               constant:280];
    [self.constraints addObject:width];
    
    NSArray * consts = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=20)-[alert]-(>=20)-|" options:0 metrics:nil views:@{@"alert": self.oldPopupView}];
    [self.constraints addObjectsFromArray:consts];
}

#pragma mark - 显示与隐藏

- (void)showInViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if ([[viewController presentedViewController] isEqual:self]) {
        return;
    }
    [viewController presentViewController:self animated:animated completion:nil];
}

- (void)dismiss:(BOOL)animated {
    [self dismissViewControllerAnimated:animated completion:nil];
}

#pragma mark - UIViewControllerTransitioning Delegate

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    return [YCPopupPresentAnimation new];
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    return [YCPopupDismissAnimation new];
}

@end
